<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Promise的几个关键问题</title>
</head>

<body>

</body>
<script>
  /*
  1、如何改变promise的状态？
    (1)resolve(value):如果当前是pendding就会变为resolved
    (2)reject(reason):如果当前是pendding就会变为rejected
    (3)抛出异常：如果当前是pendding就会变为rejected

  2、一个promise指定多个成功/失败回调函数，都会调用吗？
    当promise改变为对应状态时都会调用

  3、改变promise状态和指定回调函数谁先谁后
    (1)都有可能，正常情况下是先指定回调函数再改变状态，但也可以先改变状态再指定回调
    (2)如何先改变状态再指定回调？
      1、在执行器中直接调用resolve()/reject()
      2、延迟更长时间才才调用then()
    (3)什么时候才能得到数据？
      1、如果先指定的回调，那当状态发生改变时，回调函数就会调用，得到数据
      2、如果先改变的状态，那当指定回调时，回调函数就会调用，得到数据

  4、promise.then()返回的新的promise的结果状态由什么决定？
    (1)简单表述：由then()指定的回调函数执行的结果决定
    (2)详细表述：
      1、如果抛出异常，新promise变为rejected，reason为抛出的异常
      2、如果返回的是非promise的任意值，新promise变为resolved，value为返回的值
      3、如果返回的是另一个新promise，此promise的结果就会成为新promise的结果

  5、promise如何串联多个操作任务？
    (1)promise的then()返回一个新的promise，可以看成then()的链式调用
    (2)通过then的链式调用串联多个同步/异步任务

  6、promise异常传透？
    (1)当使用promise的then链式调用时，可以在最后指定失败的回调，
    (2)前面任何操作出了异常，都会传到最后失败的回调中处理

  7、中断promise链？
    (1)当使用promise的then链式调用时，在中间中断，不再调用后面的回调函数
    (2)办法：在回调函数中返回一个pendding状态的promise对象

   */

  // const p = new Promise((resolve, reject) => {
  //   // resolve(1)  //promise变为resolved成功状态
  //   // reject(2) //promise变为rejected失败状态
  //   // throw new Error('出错了！');  //抛出异常，promise变为rejected失败状态，reason为抛出的error
  //   throw 3   //抛出异常，promise变为rejected失败状态，reason为抛出的3
  // });

  // p.then(
  //   value => { },
  //   reason => { console.log('reason', reason); }  //reason 3
  // )

  // p.then(
  //   value => { },
  //   reason => { console.log('reason2', reason); }  //reason2 3
  // )


  // ------------------------------------------------------------------------------------------------------------
  //常规：先指定回调函数，后改变状态
  // new Promise((resolve, reject) => {
  //   setTimeout(() => {
  //     resolve(1); //后改变状态(同时指定数据)，异步执行回调函数
  //   }, 1000);
  // }).then(  //先指定回调函数，保存当前指定的回调函数
  //   value => { console.log('value', value); },
  //   reason => { console.log('reason', reason); }
  // )

  //如何先改变状态再指定回调？
  // new Promise((resolve, reject) => {
  //   resolve(1); //先改变状态(同时指定数据)
  // }).then(  //后指定回调函数，异步执行回调函数
  //   value => { console.log('value2', value); },
  //   reason => { console.log('reason2', reason); }
  // )

  // const p = new Promise((resolve, reject) => {
  //   setTimeout(() => {
  //     resolve(1); //先改变状态(同时指定数据)
  //   }, 1000);
  // });

  // setTimeout(() => {
  //   p.then(  //后指定回调函数，异步执行回调函数
  //     value => { console.log('value3', value); },
  //     reason => { console.log('reason3', reason); }
  //   )
  // }, 1100);


  // ---------------------------------------------------------------------------------------------------------
  // new Promise((resolve, reject) => {
  //   // resolve(1)  
  //   reject(2)
  // }).then(
  //   value => {
  //     console.log('onResolved1()', value);
  //     // return 2;
  //     // return {a:1}
  //     // return Promise.resolve(3)
  //     // return Promise.reject(4)
  //     throw 5;
  //   },
  //   reason => {
  //     console.log('onRejected1()', reason);
  //     // return 2;
  //     // return {a:1}
  //     // return Promise.resolve(3)
  //     // return Promise.reject(4)
  //     throw 5;
  //   }
  // ).then(
  //   value => {
  //     console.log('onResolved2()', value);
  //   },
  //   reason => {
  //     console.log('onRejected2()', reason);
  //   }
  // )

  // ---------------------------------------------------------------------------------------------------------------
  // new Promise((resolve, reject) => {
  //   setTimeout(() => {
  //     console.log('执行任务1(异步)');
  //     resolve(1)
  //   }, 1000)
  // }).then(
  //   value => {
  //     console.log('任务1的结果', value);
  //     console.log('执行任务2(同步)');
  //     return 2;
  //   }
  // ).then(
  //   value => {
  //     console.log('任务2的结果', value);
  //     return new Promise((resolve, reject) => {
  //       // 启动任务3(异步)
  //       setTimeout(() => {
  //         console.log('执行任务3(异步)');
  //         resolve(3)
  //       }, 1000)
  //     })
  //   }
  // ).then(
  //   value => {
  //     console.log('任务3的结果', value);
  //   }
  // )

  /*
    执行任务1(异步)
    任务1的结果 1
    执行任务2(同步)
    任务2的结果 2
    执行任务3(异步)
    任务3的结果 3
   */

  //  -----------------------------------------------------------------------------------------------------
  new Promise((resolve, reject) => {
    // resolve(1);
    reject(1)
  }).then(
    value => {
      console.log('onResolved1()', value);
      return 2;
    },
    // 没写catch，就相当于写了下面这句
    // reason => { throw reason }
  ).then(
    value => {
      console.log('onResolved2()', value);
      return 3;
    },
    // 没写catch，就相当于写了下面这句
    reason => { throw reason }
  ).then(
    value => {
      console.log('onResolved3()', value);
    },
    // 没写catch，就相当于写了下面这句
    // reason => { throw reason }
    // 也可以是下面这句
    reason => Promise.reject(reason)
  ).catch(
    reason => {
      console.log('onRejected()', reason);
      // 返回下面两句，进入失败的回调
      // throw reason;
      // return Promise.reject(reason)
      return new Promise(() => { }) //返回一个pendding的promise，中断promise链
    }
  ).then(
    value => {
      console.log('onResolved4()', value);
    },
    reason => {
      console.log('onRejected2()', reason);
    }
  )











</script>

</html>